www.gusucode.com > VC 自编SQL数据库(服务端+客户端) > VC 自编SQL数据库(服务端+客户端)/code/www.NewXing.com/sql/Server/StepExec.cpp
// StepExec.cpp : implementation file // #include "stdafx.h" #include "miniSQL.h" #include "MainFrm.h" #include "StepExec.h" #include "LogDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define CMD(DO) m_Cmd.GetAt( m_Cmd.FindIndex( DO ) ) extern CMiniSQLApp theApp; ///////////////////////////////////////////////////////////////////////////// // CStepExec CStepExec::CStepExec( CString& str ) : CLexAnalyzer( str ) { } CStepExec::~CStepExec() { } void CStepExec::ErrorKey( int i ) { Lex temp = CMD(i); if( temp.key == User ) throw Error( UNKNOWN_ID, 0, temp.str ); else throw Error( SYNTAX_ERROR, 0, temp.str ); } CString CStepExec::GetID( int& i ) { Lex temp = CMD(++i); if( temp.key != User ) throw Error( SYNTAX_ERROR, 0, temp.str ); return temp.str; } CEntryAttr CStepExec::GetDef( int& i ) { CEntryAttr attr; if( CMD(++i).key != LEFT_PAR ) ErrorKey( i ); do { CString id_name = GetID( i ); CItemType type; switch( CMD(++i).key ) { case _INT : type = _INT; break; case _LONG : type = _LONG; break; case _FLOAT : type = _FLOAT; break; case _DATE : type = _DATE; break; case _STRING : if( CMD(++i).key != LEFT_PAR || CMD(++i).key != Digit || CMD(++i).key != RIGHT_PAR ) ErrorKey( i ); type = CItemType( _STRING, atoi( (LPCTSTR)CMD(i-1).str ) ); if( type.size > 0 ) break; default : Error( SYNTAX_ERROR, 0, CMD(i).str ); } attr.push( CItemAttr( (LPCTSTR)id_name, type ) ); } while( CMD(++i).key == SEPARATOR ); --i; if( CMD(++i).key != RIGHT_PAR ) ErrorKey( i ); return attr; } int CStepExec::GetStrs( int& i, STR_LIST& ret, bool id, bool par ) { if( par && CMD(++i).key != LEFT_PAR ) ErrorKey( i ); do { i++; if( ( id && CMD(i).key != User && CMD(i).key != MUL ) || ( !id && CMD(i).key != String && CMD(i).key != Digit && CMD(i).key != NUL ) ) ErrorKey( i ); if( CMD(i).key == MUL ) { ret.RemoveAll(); return 0; } if( CMD(i).key != NUL ) ret.AddTail( CMD(i).str ); else { char str = -1; ret.AddTail( CString(str) ); } } while( CMD(++i).key == SEPARATOR ); --i; if( par && CMD(++i).key != RIGHT_PAR ) ErrorKey( i ); return ret.GetCount(); } CString CStepExec::GetStr( int& i, bool id, bool par ) { CString str; if( par && CMD(++i).key != LEFT_PAR ) ErrorKey( i ); i++; if( ( id && CMD(i).key != User ) || ( !id && CMD(i).key != String && CMD(i).key != Digit && CMD(i).key != NUL ) ) ErrorKey( i ); if( CMD(i).key != NUL ) str = CMD(i).str; else { char a = -1; str= CString( a ); } if( par && CMD(++i).key != RIGHT_PAR ) ErrorKey( i ); return str; } void CStepExec::GetCondition( CTable& table, int& i, RESULT& ret ) { if( CMD(i+1).key != WHERE ) { table.search( ret ); return ; } i++; STR_PAIR equ, bet1, bet2; CString str; do { switch( CMD(i+2).key ) { case EQU: equ.first.AddTail( GetStr( i, true ) ); i++; equ.second.AddTail( GetStr( i, false ) ); break; case BETWEEN: str = GetStr( i, true ); bet1.first.AddTail( str ); bet2.first.AddTail( str ); i++; bet1.second.AddTail( GetStr( i, false ) ); if( CMD(++i).key != AND ) ErrorKey( i ); bet2.second.AddTail( GetStr( i, false ) ); break; default: ErrorKey( i+2 ); } }while( CMD(++i).key == AND ); i--; if( equ.first.GetCount() && !bet1.first.GetCount() ) { table.search( ret, equ ); return ; } else if( !equ.first.GetCount() && bet1.first.GetCount() ) table.search( ret, bet1, bet2 ); else if( equ.first.GetCount() && bet1.first.GetCount() ) table.search( ret, equ, bet1, bet2 ); else throw Error(); } void CStepExec::GetSet( int& i, STR_PAIR& ret ) { do { ret.first.AddTail( GetStr( i, true ) ); if( CMD(++i).key != EQU ) ErrorKey( i ); ret.second.AddTail( GetStr( i, false ) ); }while( CMD(++i).key == SEPARATOR ); i--; } void CStepExec::Exec() { m_Cmd.RemoveAll(); m_Cmd.AddTail( CLexAnalyzer::NextToken() ); while( m_Cmd.GetTail().key != EndOfFile ) { if( m_Cmd.GetTail().key == SEMICOLON ) { StepExec(); m_Cmd.RemoveAll(); } m_Cmd.AddTail( CLexAnalyzer::NextToken() ); } } void CStepExec::SingleExec() { m_Cmd.RemoveAll(); do m_Cmd.AddTail( CLexAnalyzer::NextToken() ); while( m_Cmd.GetTail().key != EndOfFile && m_Cmd.GetTail().key != SEMICOLON ); if( m_Cmd.GetTail().key == SEMICOLON ) StepExec(); } void CStepExec::StepExec() { int i = 0; switch( CMD(i++).key ) { case CREATE: if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) ) if( CMD(i).key == _TABLE ) { CString tname = GetID( i ); CEntryAttr attr = GetDef( i ); if ( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); CTable table( (LPCTSTR)tname, attr ); theApp.OnRefreshFileTree(); table.close(); Message( (CString)"Successful : Created table \"" + tname +"\"\n" ); } else if( CMD(i).key == INDEX || CMD(i).key == UNIQUE && CMD(i+1).key == INDEX ) { bool dup = true; if( CMD(i).key == UNIQUE ) dup = false, ++i; CString iname = GetID( i ); if( CMD(++i).key != ON ) ErrorKey( i ); CString tname = GetID( i ); STR_LIST name_list; GetStrs( i, name_list, true, true ); if( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); CTable( (LPCTSTR)tname ).create_index( (LPCTSTR)iname, name_list, dup ); CMainFrame* pMainFrm = ( CMainFrame* )AfxGetMainWnd(); pMainFrm->m_FileBar.InsertIndex( tname, iname ); Message( (CString)"Successful : Created index \"" + iname +".bpt\" on table \"" + tname + "\"\n" ); } else ErrorKey( i ); else throw Error( ERROR_AUTHOR, 0, _T("") ); break; case INSERT: if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) ) { if( CMD(i).key != INTO ) i--; CString tname = GetID( i ); STR_PAIR input; if( CMD(i+1).key == LEFT_PAR ) GetStrs( i, input.first, true, true ); if( CMD(++i).key != VALUES ) ErrorKey( i ); GetStrs( i, input.second, false, true ); if( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); CTable table( (LPCTSTR)tname ); table.insert( input ); Message( "Operation insert successful.\n" ); } else throw Error( ERROR_AUTHOR, 0, _T("") ); break; case SELECT: { STR_LIST name_list; GetStrs( --i, name_list, true ); if( CMD(++i).key != FROM ) ErrorKey( i ); CString tname = GetID( i ); if( !name_list.GetCount() && CMD(i+1).key == SEMICOLON ) { CString tpath( theApp.dir ); tpath = tpath + "\\" + tname + ".msl"; CMSLDoc* pDoc; if( pDoc = theApp.IsDocExist( tname + ".msl" ) ) pDoc->OnCloseDocument(); theApp.OpenDocumentFile( tpath ); break; } CTable table( (LPCTSTR) tname ); RESULT res; GetCondition( table, i, res ); if( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); table.select( res, name_list ); table.close(); CString temp; temp.Format( "Select successful : Total %d entries selected.\n", res.GetCount() ); Message( temp ); } break; case _DELETE: if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) ) if( CMD(i).key == FROM ) { CTable table( (LPCTSTR) GetID( i ) ); RESULT res; GetCondition( table, i, res ); if( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); table.remove( res ); CString temp; temp.Format( "Delete successful : Total %d entries deleted.\n", res.GetCount() ); Message( temp ); } else ErrorKey( i ); else throw Error( ERROR_AUTHOR, 0, _T("") ); break; case UPDATE: if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) ) { CTable table( (LPCTSTR)GetID( --i ) ); if( CMD(++i).key != SET ) ErrorKey( i ); STR_PAIR set; GetSet( i, set ); RESULT res; GetCondition( table, i, res ); if( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); table.update( res, set ); CString temp; temp.Format( "Update successful : Total %d entries updated.\n", res.GetCount() ); Message( temp ); } else throw Error( ERROR_AUTHOR, 0, _T("") ); break; case DROP: if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) ) if( CMD(i).key == _TABLE ) { CString tname = GetID( i ); if( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); CTable( (LPCTSTR)tname ).drop(); CMainFrame* pMainFrm = ( CMainFrame* )theApp.m_pMainWnd; pMainFrm->m_FileBar.DelFile( tname ); Message( (CString)"Successful : Dropped table \"" + tname +"\"\n" ); } else if( CMD(i).key == INDEX ) { CString iname = GetID( i ); if( CMD(++i).key != ON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); CString tname = GetID( i ); if( CMD(++i).key != SEMICOLON ) throw Error( SYNTAX_ERROR, 0, CMD(i).str ); CTable( (LPCTSTR)tname ).drop_index( (LPCTSTR)iname ); CMainFrame* pMainFrm = ( CMainFrame* )AfxGetMainWnd(); pMainFrm->m_FileBar.DropIndex( tname, iname ); Message( (CString)"Successful : Dropped index \"" + iname + ".bpt\" on table\"" + tname + "\"\n" ); } else ErrorKey( i ); else throw Error( ERROR_AUTHOR, 0, _T("") ); break; case EXIT: theApp.Exit(); break; default: ErrorKey( --i ); } }